package com.csh.order.controller;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.csh.order.entity.TbAdmin;
import com.csh.order.entity.TbGoods;
import com.csh.order.entity.TbLog;
import com.csh.order.entity.dto.GoodsEs;
import com.csh.order.entity.dto.LogGoodsAdmin;
import com.csh.order.feign.FeignClients;
import com.csh.order.mapper.TbGoodsMapper;
import com.csh.order.mapper.TbLogMapper;
import com.csh.order.service.TbGoodsService;
import com.csh.utils.AliyunOssUtil;
import com.csh.utils.ResultResponse;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.jettison.json.JSONString;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {
    @Autowired
    TbGoodsService tbGoodsService;
    @Autowired
    TbGoodsMapper tbGoodsMapper;
    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    FeignClients feignClients;
    @Autowired
    TbLogMapper tbLogMapper;
    private static boolean cj=false;

    /**
     *创建索引加映射
     * @return
     */
    @PostMapping("/esIndexes")
    public String EsIndexes(){
        if(cj){
            System.out.println("已创建无需在创建了");
            return null;
        }
        if(!elasticsearchRestTemplate.indexOps(TbGoods.class).exists()){
            System.out.println("创建成功了");
            elasticsearchRestTemplate.indexOps(TbGoods.class).create();
            //常见索引
            Document mapping = elasticsearchRestTemplate.indexOps(TbGoods.class).createMapping();
            elasticsearchRestTemplate.indexOps(TbGoods.class).putMapping(mapping);
        }
        cj=true;
        return null;
    }
    /**
     * 增量同步全量同步
     */
    @PostMapping("/incrementSynchronization")
    public void incrementSynchronization(){
        Date keyTime= (Date) redisTemplate.opsForValue().get("key");
        System.out.println(keyTime);
        if(keyTime==null){
            QueryWrapper<TbGoods> wrapper=new QueryWrapper<>();
            wrapper.lambda().orderByDesc(TbGoods::getCreatTime);
            List<TbGoods> goods = tbGoodsMapper.selectList(wrapper);
            for (TbGoods good : goods) {
                System.out.println(good+"===========");
            }
            elasticsearchRestTemplate.save(goods);
            TbGoods tbGoods = goods.get(0);
            Date creatTime = tbGoods.getCreatTime();
            redisTemplate.opsForValue().set("key",creatTime);
            log.info(String.valueOf(creatTime));
        }else{
            QueryWrapper<TbGoods> wrapper=new QueryWrapper<>();
            wrapper.lambda().orderByDesc(TbGoods::getCreatTime);
            wrapper.lambda().gt(TbGoods::getCreatTime,keyTime);
            List<TbGoods> goods = tbGoodsMapper.selectList(wrapper);
            if(goods!=null && goods.size()>0){
                elasticsearchRestTemplate.save(goods);
                TbGoods tbGoods = goods.get(0);
                Date creatTime = tbGoods.getCreatTime();
                redisTemplate.opsForValue().set("key",creatTime);
                log.info("增量同步:"+creatTime);
            }

        }
        return;

    }

    /**
     *  ES中获取商品信息进行列表展示。
     *  ES完成商品模糊搜索，日期范围查询，价格范围查询，价格排序和高亮展示。
     *  列表上方展示商品的销售量和点击率，并对销售量和点击率进行排序展示。
     *
     * @return
     */
    @PostMapping("/searchByWord")
    public Map searchByWord(@RequestBody GoodsEs goodsEs) {
        //分页
        PageRequest pageRequest = PageRequest.of(goodsEs.getPageNum() - 1, goodsEs.getPageSize());
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        //构造查询条件
            //模糊查询
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if(goodsEs.getGoodsName()==null){
            //没有模糊查询的时候查询全部数据
           boolQueryBuilder.must(QueryBuilders.matchAllQuery());

        }else{
            //有模糊查询
            boolQueryBuilder.must(QueryBuilders.matchQuery("goodsName", goodsEs.getGoodsName()));

        }
        //高亮展示
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='red'>").postTags("</font>").field("goodsName");

        FieldSortBuilder price=null;
        if(goodsEs.getGoodsQuantity()!=null){
            //销
            price= new FieldSortBuilder("goodsQuantity").order(SortOrder.DESC);
        }if(goodsEs.getClickRate()!=null){
            //销售量
            price= new FieldSortBuilder("clickRate").order(SortOrder.DESC);
        }
        if(goodsEs.getGoodsQuantity()==null&&goodsEs.getClickRate()==null){
            //价格排序
            price = new FieldSortBuilder("price").order(SortOrder.DESC);
        }

        //日期区间查询
        SimpleDateFormat sdf=new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
        if(goodsEs.getOneTime()!=null){
            String format = sdf.format(goodsEs.getOneTime());
            boolQueryBuilder.must(
                    QueryBuilders.rangeQuery("creatTime").gt(format)
            );
        }
        if(goodsEs.getEndTime()!=null){
            String format = sdf.format(goodsEs.getEndTime());
            boolQueryBuilder.must(
                    QueryBuilders.rangeQuery("creatTime").lt(format)
            );
        }
        //价格区间
        if(goodsEs.getMin()!=null){
            boolQueryBuilder.must(
                    QueryBuilders.rangeQuery("price").gt(goodsEs.getMin())
            );
        }
        if(goodsEs.getMax()!=null){
            boolQueryBuilder.must(
                    QueryBuilders.rangeQuery("price").lt(goodsEs.getMax())
            );
        }
        //条件记录数
        builder.withPageable(pageRequest).withHighlightBuilder(highlightBuilder).withSort(price).withQuery(boolQueryBuilder);
        
        //查询
        SearchHits<TbGoods> search = elasticsearchRestTemplate.search(builder.build(), TbGoods.class);
        long count = elasticsearchRestTemplate.count(builder.build(), TbGoods.class);

        List<SearchHit<TbGoods>> searchHits = search.getSearchHits();
        List<TbGoods> list=new ArrayList<>();
        Map map=new HashMap();
        searchHits.forEach(item->{
            TbGoods tbGoods= item.getContent();
            List<String> goodsName = item.getHighlightField("goodsName");
            if(goodsName!=null&&goodsName.size()>0){
                String s = goodsName.get(0);
                tbGoods.setGoodsName(s);
            }
            list.add(tbGoods);


        });
        map.put("list",list);
        map.put("pageNum",goodsEs.getPageNum());
        map.put("pageSize",goodsEs.getPageSize());
        map.put("total",count);
        return map;
    }


    /**
     * 点击商品进入商品购买页面，展示所有种类的商品，和商品是否有货，以及商品数量。并记录这个商品的点击率。
     */
    @PostMapping("/findGoodsPage")
    public ResultResponse findGoodsPage(){

        return tbGoodsService.findGoodsPage();
    }

    /**
     * 图片上传
     */
    @PostMapping("/imageUpload")
    public ResultResponse imageUpload(@RequestParam("file")MultipartFile file){
        String upload = AliyunOssUtil.OSS().upload(file);
        return ResultResponse.SUCCESS(upload);
    }

    @PostMapping("/findGoodsUpdate")
    public ResultResponse findGoodsUpdate(@RequestBody LogGoodsAdmin logGoodsAdmin){
        //用户Id
        Integer adminId = logGoodsAdmin.getAdminId();
        TbAdmin tbAdmin=new TbAdmin();
        tbAdmin.setId(adminId);
        //使用feign调用 从用户服务中找到这个用户的信息
        TbAdmin admins= feignClients.adminIdList(tbAdmin);

        //判断用户时候有卖过这个商品  要用:用户名+手机号+商品的Id查询商品的详情信息
        QueryWrapper<TbLog> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda().eq(TbLog::getName,admins.getName()).eq(TbLog::getPhone,admins.getPhone()).eq(TbLog::getGoodsId,logGoodsAdmin.getGoodsId());
        TbLog tbLog = tbLogMapper.selectOne(queryWrapper);
        //当查询到这个商品详情的信息后证明我们已经购买过这个商品了
        // 不管有购买过的商品数量为多少.只要是点击并且有购买过就先返回提示(你已经购买过了)
            //前端会弹出一个框把提示信息打印,如果用户非要购买的话就在从前端返回一个带有标识符的信息，证名我们已经提示过了，但是用户还是要够买
            //有这个提示符的话就直接判断有没有购买超过2次，如果购买超过2次的话就提示（不能在购买了）
            //有这个提示符也没有购买超过两个,就可以购买，提示商品详情表,并且修改商品的数量+点击率+商品销量
        //没有购买过不提示
        if(tbLog!=null){
            //证名已经购买过了
            if(logGoodsAdmin.getBsf()==null){
                if(logGoodsAdmin.getBsf()==null){
                    return ResultResponse.FAILED(2000,"你以购买过这个商品了确定还要继续后买吗？");
                }
            }
            //当购买了3次就不给购买了
            if(tbLog.getNum()>2){
                return ResultResponse.FAILED(5000,"该商品您以购买3次无法在进行购买");
            }
            //判断已经购买过了但是还可以继续购买 值可以随便写
            logGoodsAdmin.setNumBsf("kkkk");
        }

        String s = JSON.toJSONString(logGoodsAdmin);
        rabbitTemplate.convertAndSend("public_ribbit_mq","binding_goods",s);




        return ResultResponse.FAILED(200,"购买成功");

    }


}
